﻿/*
 * Copyright (c) Martin Kinkelin
 *
 * See the "License.txt" file in the root directory for infos
 * about permitted and prohibited uses of this code.
 */

using System;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Security;

namespace Jarf
{
	static class Program
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main()
		{
			string[] args = Environment.GetCommandLineArgs();

			// we need to make sure our event source exists
			// if it doesn't, we usually end up with a security exception and
			// need to create it using elevated privileges (UAC popup)
			try
			{
				if (!EventLog.SourceExists("Jarf"))
				{
					EventLog.CreateEventSource("Jarf", null);

					// exit immediately if the -i switch has been specified
					if (args.Length == 2 && args[1] == "-i")
						return;
				}
			}
			catch (SecurityException e)
			{
				// we need elevated privileges
				// launch a new admin process using the -i switch
				// the process will create the event source and exit immediately
				ProcessStartInfo startInfo = new ProcessStartInfo();
				startInfo.UseShellExecute = true;
				startInfo.FileName = Application.ExecutablePath;
				startInfo.Arguments = "-i";
				startInfo.Verb = "runas";

				// wait until the admin process has exited
				while (true)
				{
					MessageBox.Show("Jarf needs elevated privileges to create an event source for the application event log.",
						"Jarf will cause a UAC popup", MessageBoxButtons.OK, MessageBoxIcon.Information);

					try
					{
						Process adminProcess = Process.Start(startInfo);
						adminProcess.WaitForExit();
						adminProcess.Close();

						break;
					}
					catch (System.ComponentModel.Win32Exception e2)
					{
						// the user probably refused to grant us the admin rights
					}
				}
			}

			if (args.Length == 2)
			{
				// the argument is most probably a GUID of a backup task to be backed up
				BackupTask task = BackupTaskManager.Instance.LoadTask(args[1]);
				if (task == null)
					return;

				Process process = null;

				try
				{
					process = ProcessFactory.PrepareBackup(task);
					process.StartInfo.RedirectStandardOutput = true;
					process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
					process.StartInfo.RedirectStandardError = true;
					process.StartInfo.StandardErrorEncoding = Encoding.UTF8;

					process.Start();
					process.WaitForExit();

					if (process.ExitCode == 0)
					{
						task.LastBackup = DateTime.Now;

						string output = process.StandardOutput.ReadToEnd();
						Log.Instance.Write(EventLogEntryType.Information,
							string.Format("\"{0}\" successfully backed up to \"{1}\":\n\n{2}",
							task.Source, task.Destination, output));

						BackupTaskManager.Instance.SaveTask(task);
					}
					else
					{
						string error = process.StandardError.ReadToEnd();
						Log.Instance.Write(EventLogEntryType.Error,
							string.Format("Error while trying to back up \"{0}\" to \"{1}\":\n\n{2}",
							task.Source, task.Destination, error));
					}
				}
				catch (Exception e)
				{
					Log.Instance.Write(EventLogEntryType.Error,
						string.Format("Exception while trying to back up \"{0}\" to \"{1}\":\n\n{2}",
						task.Source, task.Destination, e.Message));
				}
				finally
				{
					if (process != null)
						process.Close();
				}
			}
			else
			{
				// show the main form
				Application.EnableVisualStyles();
				Application.SetCompatibleTextRenderingDefault(false);
				Application.Run(new MainForm());
			}
		}
	}
}
